/*+*********************************************************
Filename: B02_fft-ip_test\src\top.v
Description:
  Learning the usage of Gowin FFT IP.
  Test the output signal of FFT IP.

Modification:
2024.03.26 creation by H.Zheng
03.28 copy and modified from test01, use simpleuart_tx32 H.Zheng
**********************************************************-*/


module top(
	input wire clk,
	input wire rst_n,
	input wire [1:0] button,
  output wire [5:0] led, 

  output wire uart_tx_pin

);

/**
 * clock section
 */
  wire clk1m;
  wire clk6m;
  PLL_6M PLL6m(
    .clkout(clk6m),
    .clkoutd(clk1m),
    .clkin(clk)
  );

/**
 * data generator: provide data to FFT
 */
  reg [20:0] counter_1s;

  always @(posedge clk1m) begin
      counter_1s <= counter_1s + 1'd1;
  end

  wire clk_1s = counter_1s[19];
  wire clk_2s = counter_1s[20];


  wire fft_clk = clk_1s;

  //use button[0] to triger data reset and start fft
  reg [1:0] button0_input_reg;
  always @(posedge fft_clk) begin
    button0_input_reg <= {button0_input_reg[0], button[0]};
  end

  wire fft_start_pulse = button0_input_reg[1] & (~button0_input_reg[0]); //catch button[0] negative edge, 1 fft_clk width


/**
 * FFT
 */
  wire mfft_busy_flag;
  wire mfft_input_data_flag;
  wire mfft_start_output_data_flag;
  wire mfft_output_data_flag;
  wire [15:0] mfft_xk_re_o, mfft_xk_im_o;
  wire [2:0] mfft_idx;

  wire mfft_clk = fft_clk;
  wire mfft_rst = ~rst_n;
  wire mfft_start = fft_start_pulse;

//  wire [15:0] xn_re_i = (~mfft_idx[2]) ? 16'sd10000 : -16'sd10000;  //first 4 data is +10000, next 4 is -10000
  wire [15:0] xn_re_i = (~mfft_idx[2]) ? 16'd10000 : 16'd0;  //first 4 data is 10000, next 4 is 0

	FFT_Top_8p m_fft(
		.idx(mfft_idx), //output [2:0] idx
		.xk_re(mfft_xk_re_o), //output [15:0] xk_re
		.xk_im(mfft_xk_im_o), //output [15:0] xk_im
		.sod(), //output sod
		.ipd(mfft_input_data_flag), //output ipd
		.eod(), //output eod
		.busy(mfft_busy_flag), //output busy
		.soud(mfft_start_output_data_flag), //output soud
		.opd(mfft_output_data_flag), //output opd
		.eoud(), //output eoud
		.xn_re(xn_re_i), //input [15:0] xn_re
		.xn_im(16'b0), //input [15:0] xn_im
		.start(mfft_start), //input start
		.clk(mfft_clk), //input clk
		.rst(mfft_rst), //input rst
		.ifft(1'b0) //input ifft
	);


/**
 * uart section
 */

parameter                        CLK_FRE  = 27;//Mhz
parameter                        UART_FRE = 115200;//hz
wire[31:0]                         tx_data;
wire                              tx_data_valid;
wire                             tx_data_ready;


//big endian mode
assign tx_data = {mfft_xk_re_o, mfft_xk_im_o};

//uart tx pulse
  reg [1:0] fft_clk_pulse_reg;
  always @(posedge clk) begin
    fft_clk_pulse_reg <= {fft_clk_pulse_reg[0], mfft_clk};
  end

  //mfft_clk negedge and mfft_output_data_flag
  assign tx_data_valid = mfft_output_data_flag & (fft_clk_pulse_reg[1] & (~fft_clk_pulse_reg[0])); 

  simpleuart_tx32 #(.CLK_FRE(CLK_FRE),.BAUD_RATE(UART_FRE)) uart_tx_inst(
    .clk(clk),
    .resetn(rst_n),
    .ser_tx(uart_tx_pin),
    .reg_dat_we(tx_data_valid),
    .reg_dat_di(tx_data),
    .reg_dat_wait()
  );


/**
 * led
 */

  assign led = {~mfft_clk, ~mfft_input_data_flag, ~mfft_output_data_flag, ~mfft_start, ~mfft_start_output_data_flag, ~mfft_busy_flag};
//  assign led = {fft_out_zero_re, fft_out_zero_im, ifft_out_zero_re, ifft_out_zero_im, outfifo_outdata_zero , ~loud_voice};
//  assign led = {~mifft_output_data_flag, ~outfifo_af_flag, ~Almost_Full_o, ~mfft_busy_flag, ~mifft_busy_flag , ~loud_voice};


endmodule